export const metadata = {
  description: "Share CoValues in Jazz through public sharing and invite links. Enable collaboration by granting access to everyone or specific users with different permission levels."
};

import { Alert, CodeGroup, ContentByFramework, ExpoLogo, ReactLogo, RNLogo, SvelteLogo, VanillaLogo, TabbedCodeGroup, TabbedCodeGroupItem } from '@/components/forMdx';

# Public sharing and invites

## Public sharing

You can share CoValues publicly by setting the `owner` to a `Group`, and granting access to "everyone".

<CodeGroup>
```ts index.ts#Basic
```
</CodeGroup>

You can also use `makePublic(role)` alias to grant access to everyone with a specific role (defaults to `reader`).

<CodeGroup className="[&_span]:whitespace-normal">
```ts index.ts#MakePublic
```
</CodeGroup>

<ContentByFramework framework="react">
This is done in the [chat example](https://github.com/garden-co/jazz/tree/main/examples/chat) where anyone can join the chat, and send messages.
</ContentByFramework>

You can also [add members by Account ID](/docs/permissions-and-sharing/overview#adding-group-members-by-id).

## Invites

You can grant users access to a CoValue by sending them an invite link.

<ContentByFramework framework="react">
This is used in the [todo example](https://github.com/garden-co/jazz/tree/main/examples/todo).
</ContentByFramework>

<TabbedCodeGroup default="react" savedPreferenceKey="framework" id="create-invite-link">
  <TabbedCodeGroupItem icon={<VanillaLogo />} label="Vanilla" value="vanilla" preferWrap>
  ```tsx create-invite-link.ts#CreateLink
  ```
  </TabbedCodeGroupItem>
  <TabbedCodeGroupItem icon={<ReactLogo />} label="React" value="react" preferWrap>
  ```tsx react-snippet.tsx#CreateInviteLink
  ```
  </TabbedCodeGroupItem>
  <TabbedCodeGroupItem icon={<SvelteLogo />} label="Svelte" value="svelte" preferWrap>
  ```ts create-invite-link.svelte.ts#Basic
  ```
  </TabbedCodeGroupItem>
  <TabbedCodeGroupItem icon={<RNLogo />} label="React Native" value="react-native" preferWrap>
  ```tsx rn.tsx#CreateInviteLink
  ```
  </TabbedCodeGroupItem>
  <TabbedCodeGroupItem icon={<ExpoLogo />} label="Expo" value="react-native-expo" preferWrap>
  ```tsx expo.tsx#CreateInviteLink
  ```
  </TabbedCodeGroupItem>
</TabbedCodeGroup>

It generates a URL that looks like `.../invite/[CoValue ID]/[inviteSecret]`

In your app, you need to handle this route, and let the user accept the invitation,
as done [here](https://github.com/garden-co/jazz/tree/main/examples/todo/src/2_main.tsx).

<TabbedCodeGroup default="react" savedPreferenceKey="framework" id="consume-invite-link">
<TabbedCodeGroupItem icon={<VanillaLogo />} label="Vanilla" value="vanilla" preferWrap>
```ts create-invite-link.ts#ConsumeLink
```
</TabbedCodeGroupItem>
<TabbedCodeGroupItem icon={<ReactLogo />} label="React" value="react" preferWrap>
```tsx react-snippet.tsx#AcceptInvite
```
</TabbedCodeGroupItem>
<TabbedCodeGroupItem icon={<SvelteLogo />} label="Svelte" value="svelte" preferWrap>
```svelte svelte.svelte
```
</TabbedCodeGroupItem>
<TabbedCodeGroupItem icon={<RNLogo />} label="React Native" value="react-native" preferWrap>
```tsx rn.tsx#AcceptInvite
```
</TabbedCodeGroupItem>
<TabbedCodeGroupItem icon={<ExpoLogo />} label="Expo" value="react-native-expo" preferWrap>
```ts expo.tsx#AcceptInvite
```
</TabbedCodeGroupItem>
</TabbedCodeGroup>

You can accept an invitation programmatically by using the `acceptInvite` method on an account.

Pass the ID of the CoValue you're being invited to, the secret from the invite link, and the schema of the CoValue.

<CodeGroup>
```ts index.ts#AcceptInviteProgrammatically
```
</CodeGroup>

### Invite Secrets
The invite links generated by Jazz are convenient ways of handling invites.

In case you would prefer more direct control over the invite, you can create an invite to a `Group` using `Group.createInvite(id, role)` or `group.$jazz.createInvite(role)`.

This will generate a string starting with `inviteSecret_`. You can then accept this invite using `acceptInvite`, with the group ID as the first argument, and the invite secret as the second.

<CodeGroup preferWrap>
```ts index.ts#InviteToGroup
```
</CodeGroup>

<Alert variant="warning" title="Security Note" className="mt-4">
  **Invites do not expire and cannot be revoked.** If you choose to generate your own secrets in this way, take care that they are not shared in plain text over an insecure channel.

  One particularly tempting mistake is passing the secret as a route parameter or a query. However, this will cause your secret to appear in server logs. You should only ever use fragment identifiers (i.e. parts after the hash in the URL) to share secrets, as these are not sent to the server (see the `createInviteLink` implementation).
</Alert>

### Requesting Invites

To allow a non-group member to request an invitation to a group you can use the `writeOnly` role.
This means that users only have write access to a specific requests list (they can't read other requests).
However, Administrators can review and approve these requests.

Create the data models.

<CodeGroup>
```ts schema.ts#JoinRequest
```
</CodeGroup>

Set up the request system with appropriate access controls.

<CodeGroup>
```ts index.ts#CreateRequestsToJoin
```
</CodeGroup>

Using the write-only access users can submit requests that only administrators can review and approve.

<CodeGroup>
```ts index.ts#ApproveJoinRequest
```
</CodeGroup>
